
static void timer_worker(struct work_struct *mywork)
{
	int row, col; /* those are locals here */
	/* when thers a bigger error - power to the lcds is off
	 * then after 3 times trying to correct the error with no succes
	 * i set_bit(FLAG_READ_OFF,..) and stop checking devices */
	char times=0;
	int errors=0;
	char shouldbe;
	char isnow;
	
	if ( test_bit(FLAG_READ_OFF, &lcddev.flags) )
		return;
		
	PDEBUG_TIMER("timer_worker start");
	
	for ( row = 0; row < DISP_ROWS && times < 3; ++row ) {
		for( col = 0; col < DISP_COLS && times < 3 ; ++col ) {
			mutex_lock(&state_mutex);
			
			shouldbe = state[row][col];
			
			isnow = _read_DDRAM(row, col);
			
			if (isnow != shouldbe) {
				isnow = _read_DDRAM(row, col);
				
				if (isnow != shouldbe) {
					const unsigned int ctrl_nr = row / ROWS_PER_CTRL;
					char buff = state[row][col];
					lcddev.lcd[ctrl_nr].errors_num++;
					
					PDEBUG_TIMER("timer_worker error on: %d %d %d %02x", ctrl_nr, row, col, state[row][col]);
					
					_write_DDRAM(row, col, buff);
					++times;
					++errors;
					
					--col; /* make it check one more time */
				} else {
					times=0;
				}
			} else {
				times=0;
			}
			
			mutex_unlock(&state_mutex);
		}
	}
	
	PDEBUG_TIMER("timer_worker stop times");
	
	
	if ( errors >= DISP_COLS*DISP_ROWS/2 ) {
		PWARN("What? %d errors on lcds!", errors);
	}
	if ( times >= 3 ) {
		PERR("Reading from lcds is broken. Disabling it.");
		set_bit(FLAG_READ_OFF, &lcddev.flags);
		return;
	}
	
	schedule_delayed_work(&timer_work, checktime*HZ );
}
